#include "hplcpermitpage.h"
#include <QHBoxLayout>
#include <QVBoxLayout>

HplcPermitPage::HplcPermitPage(QWidget *parent) : QWidget(parent)
{
    setWindowTitle(tr("Hplc Permit Page"));
    setAttribute(Qt::WA_DeleteOnClose);

    m_lbSerial = new QLabel(tr("Serial"));
    m_leSerial = new QLineEdit();
    m_lbRandomCode = new QLabel(tr("Random Code"));
    m_leRandomCode = new QLineEdit();
    m_lbAvailableDays = new QLabel(tr("Available Days"));
    m_leAvailableDays = new QLineEdit();
    m_lbTips = new QLabel(tr("10000 means cracked, \n0 means timeout"));
    m_pbActive = new QPushButton(tr("Active"));
    connect(m_pbActive, &QPushButton::clicked, this, [=](){
        QByteArray ba = m_leSerial->text().toLatin1(); // must
        char *ch = ba.data();
        quint32 serial = randomString2UInt32((quint8*)ch);
        qDebug("Serial = %d\r\n", serial);

        quint32 randomCode = m_leRandomCode->text().toUInt();
        quint16 availableDays = m_leAvailableDays->text().toUInt();

        quint32 activeCode = generateActiveCode(serial, randomCode, availableDays);

        m_leActiveCode->setText(QString::number(activeCode));
    });
    m_lbActiveCode = new QLabel(tr("Active Code"));
    m_leActiveCode = new QLineEdit();

    QHBoxLayout *hblSerial = new QHBoxLayout();
    hblSerial->addWidget(m_lbSerial);
    hblSerial->addWidget(m_leSerial);
    QHBoxLayout *hblRandomCode = new QHBoxLayout();
    hblRandomCode->addWidget(m_lbRandomCode);
    hblRandomCode->addWidget(m_leRandomCode);
    QHBoxLayout *hblAvailableDays = new QHBoxLayout();
    hblAvailableDays->addWidget(m_lbAvailableDays);
    hblAvailableDays->addWidget(m_leAvailableDays);
    QHBoxLayout *hblActive = new QHBoxLayout();
    hblActive->addWidget(m_lbTips);
    hblActive->addWidget(m_pbActive);
    QHBoxLayout *hblActiveCode = new QHBoxLayout();
    hblActiveCode->addWidget(m_lbActiveCode);
    hblActiveCode->addWidget(m_leActiveCode);

    QVBoxLayout *vbl = new QVBoxLayout();
    vbl->addLayout(hblSerial);
    vbl->addLayout(hblRandomCode);
    vbl->addLayout(hblAvailableDays);
    vbl->addLayout(hblActive);
    vbl->addLayout(hblActiveCode);
    setLayout(vbl);
}

uint32_t HplcPermitPage::generateActiveCode(uint32_t serial, uint32_t randomCode, uint16_t availableDays)
{

#define ACTIVEMASK 0x050A

    uint32_t activeCode;

    //activeCode = serial;
    quint16 validateCode = serial & 0x0000FFFF;
    quint16 temp = randomCode & 0x0000FFFF;
    validateCode ^= ACTIVEMASK;
    temp ^= ACTIVEMASK;
    validateCode += temp;

    quint16 availableDays_t = (serial & 0xFFFF0000) >> 16;
    temp = (randomCode & 0xFFFF0000) >> 16;
    availableDays_t ^= ACTIVEMASK;
    temp ^= ACTIVEMASK;
    availableDays_t += temp;

    availableDays += availableDays_t;

    activeCode = ((quint32)validateCode << 16) | availableDays;

    return activeCode;
}

uint32_t HplcPermitPage::randomString2UInt32(uint8_t *str)
{
    //uint8_t strLen = strlen((const char*)str);
    //uint8_t i;
    //uint32_t ret = 0;
    //uint8_t *p = (uint8_t*)&ret;

    //if (strLen <= 4)
    //{
    //	for (i = 0; i<strLen; i++)
    //	{
    //		p[i] = str[i];
    //	}
    //}
    //else
    //{
    //	uint8_t group = strLen / 4;
    //	uint8_t remainder = strLen % 4;
    //	uint8_t j;

    //	for (i = 0; i<strLen-remainder; i += group)
    //	{
    //		for (j = 0; j<group; j++)
    //			p[i] ^= str[i + j];
    //	}

    //	if (remainder)
    //	{
    //		j = strLen - remainder;
    //		for (i = 0; i<remainder; i++)
    //		{
    //			p[i] ^= str[j++];
    //		}
    //	}
    //}

    //return ret;

    uint8_t strLen = strlen((const char*)str);
    uint8_t i, j = 0;
    uint32_t ret = 0;
    uint8_t *p = (uint8_t*)&ret;

    for (i = 0; i < strLen; i++)
    {
        p[j] ^= str[i];
        j++;
        if (j >= 4)
            j = 0;
    }

    return ret;
}
